package com.github.gaojh;

import com.github.gaojh.aop.AopInitializer;
import com.github.gaojh.config.Environment;
import com.github.gaojh.ioc.annotation.ComponentScan;
import com.github.gaojh.ioc.bean.*;
import com.github.gaojh.mvc.filter.FilterInitializer;
import com.github.gaojh.mvc.route.RouteInitializer;
import com.github.gaojh.mvc.setup.SetupAdapter;
import com.github.gaojh.mvc.setup.SetupContext;
import com.github.gaojh.mvc.setup.SetupInitializer;
import com.github.gaojh.mvc.websocket.WebSocketInitializer;
import com.github.gaojh.server.FlyingServer;
import lombok.extern.slf4j.Slf4j;

/**
 * @author gaojh
 * @since 2020/3/23
 */
@Slf4j
public class Flying {

    private ClassScanner classScanner;

    private void initBasic(Class<?> source) throws Exception {
        if (source.isAnnotationPresent(ComponentScan.class)) {
            ComponentScan componentScan = source.getAnnotation(ComponentScan.class);
            if (componentScan.value().length > 0) {
                classScanner = new BeanClassScanner(componentScan.value());
            }
        } else {
            classScanner = new BeanClassScanner(source.getPackage().getName());
        }

        startInit(classScanner);
    }

    private void startInit(ClassScanner classScanner) throws Exception {

        Initializer beanInitializer = new BeanInitializer();
        Initializer routeInitializer = new RouteInitializer();
        Initializer interceptorInitializer = new FilterInitializer();
        Initializer setupInitializer = new SetupInitializer();
        Initializer aopInitializer = new AopInitializer();
        Initializer injectInitializer = new InjectionInitializer();

        //bean初始化
        beanInitializer.init(classScanner);
        aopInitializer.init(classScanner);
        injectInitializer.init(classScanner);

        //路由初始化
        routeInitializer.init(classScanner);

        //拦截器初始化
        interceptorInitializer.init(classScanner);

        //启动设置初始化
        setupInitializer.init(classScanner);

        if (Environment.me.isEnableWebsocket()) {
            Initializer websocketInitializer = new WebSocketInitializer();
            websocketInitializer.init(classScanner);
        }
    }

    public Flying port(int port) {
        Environment.me.setPort(port);
        return this;
    }

    public Flying enableWebsocket(boolean enable) {
        Environment.me.setEnableWebsocket(enable);
        return this;
    }

    public void run(Class<?> source) {
        if (source == null) {
            throw new RuntimeException("启动类为空");
        }

        try {
            initBasic(source);
            SetupContext.getSetupRunners().forEach(SetupAdapter::run);
            FlyingServer flyingServer = new FlyingServer();
            flyingServer.start();
        } catch (Exception e) {
            log.error("启动失败", e);
            System.exit(0);
        }
    }
}
